<template>
    <div class="upload-container">
        <div class="header">
            <h1>云盘文件上传</h1>
        </div>

        <div class="upload-area">
            <el-upload class="upload-box" drag :action="uploadUrl" :headers="headers" :data="uploadParams"
                :on-success="handleUploadSuccess" :on-error="handleUploadError" :on-exceed="handleExceed"
                :accept="'.jpg,.jpeg,.png,.gif,.bmp,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.zip,.rar,.7z,.mp3,.mp4,.avi,.wmv,.mkv,.flv,.mov,.wav,.mpg,.mpeg,.mp4,.webm,.ogg,.ogv,.avi,.wmv,.mov,.aac,.flac'"
                :before-upload="beforeUpload" :limit="1" :auto-upload="true">
                <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                <div class="el-upload__text">
                    拖拽文件到此处或 <em>点击上传</em>
                </div>
                <template #tip>
                    <div class="el-upload__tip">
                        单次只能上传一个文件，大小不超过100MB
                    </div>
                </template>
            </el-upload>
        </div>

        <el-dialog v-model="dialogVisible" title="上传成功" width="500px" center>
            <div class="success-info">
                <div class="info-item">
                    <span class="label">上传时间:</span>
                    <span class="value">{{ fileInfo?.createTime }}</span>
                </div>
                <div class="info-item">
                    <span class="label">文件名:</span>
                    <span class="value">{{ fileName }}</span>
                </div>
                <div class="info-item">
                    <span class="label">文件大小:</span>
                    <span class="value">{{ formatFileSize(fileInfo?.fileSize) }}</span>
                </div>
                <div class="info-item">
                    <span class="label">文件类型:</span>
                    <span class="value">{{ fileInfo?.fileType }}</span>
                </div>
                <div class="info-item">
                    <span class="label">访问码:</span>
                    <span class="access-code">{{ fileInfo?.accessCode || '####' }}</span>
                    <el-button type="primary" link @click="copyAccessCode">复制</el-button>
                </div>
                <div class="info-item">
                    <span class="label">分享链接:</span>
                    <div class="link-box">
                        <el-input v-model="shareLink" readonly></el-input>
                        <el-button type="primary" @click="copyShareLink">复制</el-button>
                    </div>
                </div>
            </div>
            <template #footer>
                <div class="dialog-footer">
                    <el-button @click="dialogVisible = false">关闭</el-button>
                    <el-button type="primary" @click="uploadAnother">继续上传</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { UploadFilled } from '@element-plus/icons-vue'
import list from '@/utils/url.js'

// 上传URL
const uploadUrl = ref(import.meta.env.VITE_APP_API_URL + import.meta.env.VITE_APP_BASE_API + list.list_file_api.uploadFile)

// 上传参数
const uploadParams = reactive({
    subPath: 'cloud',
    specialPrefix: 'share'
})

// 文件信息
const fileInfo = ref(null)
const fileName = ref('')
const dialogVisible = ref(false)

// 构建分享链接
const shareLink = computed(() => {
    if (!fileInfo.value || !fileInfo.value.id || !fileInfo.value.accessCode) {
        return ''
    }
    // 构建分享链接，根据实际情况调整链接格式
    const baseUrl = import.meta.env.VITE_APP_API_URL + import.meta.env.VITE_APP_BASE_API || window.location.origin
    return `${baseUrl}/v1/file/download?id=${fileInfo.value.id}&code=${fileInfo.value.accessCode}`
})

// 请求头
const headers = {
    'token': localStorage.getItem('token'),
    'ClientIP': localStorage.getItem('ClientIP')
}

// 上传前检查
const beforeUpload = (file) => {
    // 保存文件名，因为后端返回数据中可能没有原始文件名
    fileName.value = file.name

    const maxSize = 100 * 1024 * 1024 // 100MB
    if (file.size > maxSize) {
        ElMessage.error('文件大小不能超过100MB!')
        return false
    }
    return true
}

// 上传成功处理
const handleUploadSuccess = (res, file) => {
    if (res.code === 200) {
        console.log('上传成功', res)
        // 直接保存整个返回的data对象到fileInfo
        fileInfo.value = res.data
        // 打开对话框
        dialogVisible.value = true

        ElMessage.success('文件上传成功,请等待管理员审核')
    } else {
        ElMessage.error('上传失败: ' + res.msg)
    }
}

// 上传失败处理
const handleUploadError = (error) => {
    console.error('上传错误:', error)
    ElMessage.error('文件上传失败，请重试')
}

// 超出限制处理
const handleExceed = () => {
    ElMessage.warning('一次只能上传一个文件')
}

// 复制访问码
const copyAccessCode = () => {
    if (!fileInfo.value || !fileInfo.value.accessCode) {
        ElMessage.warning('没有可用的访问码');
        return;
    }

    // 先尝试使用现代 Clipboard API
    if (navigator.clipboard && window.isSecureContext) {
        navigator.clipboard.writeText(fileInfo.value.accessCode)
            .then(() => ElMessage.success('访问码已复制'))
            .catch(() => {
                // 如果现代API失败，回退到传统方法
                fallbackCopyTextToClipboard(fileInfo.value.accessCode);
            });
    } else {
        // 直接使用传统方法
        fallbackCopyTextToClipboard(fileInfo.value.accessCode);
    }
}

// 传统复制方法
const fallbackCopyTextToClipboard = (text) => {
    const textArea = document.createElement('textarea');
    textArea.value = text;

    // 隐藏临时元素但确保其可以被选择
    textArea.style.position = 'fixed';
    textArea.style.left = '0';
    textArea.style.top = '0';
    textArea.style.opacity = '0';

    document.body.appendChild(textArea);
    textArea.focus();
    textArea.select();

    try {
        const successful = document.execCommand('copy');
        if (successful) {
            ElMessage.success('内容已复制');
        } else {
            ElMessage.error('复制失败，请手动复制');
        }
    } catch (err) {
        console.error('复制操作失败:', err);
        ElMessage.error('复制失败，请手动复制');
    }

    document.body.removeChild(textArea);
}

// 复制分享链接
const copyShareLink = () => {
    if (!shareLink.value) {
        ElMessage.warning('没有可用的分享链接');
        return;
    }

    // 先尝试使用现代 Clipboard API
    if (navigator.clipboard && window.isSecureContext) {
        navigator.clipboard.writeText(shareLink.value)
            .then(() => ElMessage.success('分享链接已复制'))
            .catch(() => {
                // 如果现代API失败，回退到传统方法
                fallbackCopyTextToClipboard(shareLink.value);
            });
    } else {
        // 直接使用传统方法
        fallbackCopyTextToClipboard(shareLink.value);
    }
}

// 继续上传
const uploadAnother = () => {
    dialogVisible.value = false
    fileInfo.value = null
    fileName.value = ''
}

// 格式化文件大小
const formatFileSize = (size) => {
    if (!size) return '0 B'

    // 如果是以 KB、MB 等为单位的字符串，直接返回
    if (typeof size === 'string' && /^[\d.]+(KB|MB|GB|TB)$/.test(size)) {
        return size
    }

    // 如果是数字，按照 B, KB, MB, GB, TB 格式化
    const units = ['B', 'KB', 'MB', 'GB', 'TB']
    let index = 0
    let fileSize = Number(size)

    // 后端可能返回的是MB为单位，如果数值很小但大于0，可能已经是MB了
    if (fileSize > 0 && fileSize < 1) {
        return `${fileSize} MB`
    }

    while (fileSize >= 1024 && index < units.length - 1) {
        fileSize /= 1024
        index++
    }

    return `${fileSize.toFixed(2)} ${units[index]}`
}
</script>

<style scoped>
.upload-container {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
}

.header {
    text-align: center;
    margin-bottom: 2rem;
}

.header h1 {
    color: var(--el-color-primary);
    font-size: 2rem;
}

.upload-area {
    margin-bottom: 2rem;
}

.upload-box {
    width: 100%;
}

.success-info {
    padding: 1rem;
}

.info-item {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
}

.label {
    width: 80px;
    font-weight: bold;
    flex-shrink: 0;
}

.value {
    word-break: break-all;
}

.access-code {
    font-size: 1.5rem;
    font-weight: bold;
    color: var(--el-color-danger);
    margin-right: 0.5rem;
    letter-spacing: 2px;
}

.link-box {
    display: flex;
    flex: 1;
    margin-left: 0.5rem;
}

.link-box .el-input {
    margin-right: 0.5rem;
}

.dialog-footer {
    display: flex;
    justify-content: center;
    gap: 1rem;
}
</style>